﻿using System;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.IO;            //Path 
using System.Reflection;    //Assembly 

//using Microsoft.Xna.Framework.Storage;

namespace Cards
{
    public class Deck
    {
        #region Variables

        //first object is number of card, second is position
        public int[] deck;

        //and array to hold the contents of the temporary right hand deck
        public int[] rightHandDeck;

        //The maximum number of cards in a given deck
        static int MAXCARDS;





        //the location in the deck that is the top card
        public int topCard;

        public Deck(int maxCards)
        {
            MAXCARDS = maxCards + 1;

            //Main deck of cards
            deck = new int[MAXCARDS];
            //temporary deck of cards
            rightHandDeck = new int[MAXCARDS];

            topCard = 1;

            //Set all elements ofthe array equal to their index
            for (int i = 0; i <= MAXCARDS - 1; i++)
            {
                deck[i] = i % 52;
            }
            //set the 52nd and 104th element to 52 because the mod (%) operator made it zero
            deck[52] = 52;
            deck[104] = 52;
            //add more for more decks of cards i.e. deck[156] = 52;


        }

        public Deck(int maxCards, bool isBoard, string xmlPath)
          {
              //load the xml into an XmlDocument 
              XmlDocument doc = new XmlDocument();
              doc.Load(xmlPath);

              //get all "CARD" nodes  
              XmlNodeList cardNodes = doc.SelectNodes("/BOARD_ORIENTATION_1/CARD");
              //create an array with sufficient space 
              int[] cards = new int[cardNodes.Count];

              //iterate through the XmlNodes and parse their string values to int 
              for (int cardIndex = 0; cardIndex < cardNodes.Count; cardIndex++)
              {
                  cards[cardIndex] = int.Parse(cardNodes[cardIndex].InnerText);
              }

              for (int i = 0; i < 100; i++)
              {
                  this.deck[i] = cards[i];
              }
          }

        #endregion

        /*
        /// <summary>
        /// Load your content.
        /// </summary>
        protected override void LoadContent()
        {
            //spriteBatch = new SpriteBatch(GraphicsDevice);
        }
        */

        /// <summary>
        /// Initialize Variables.
        /// </summary>
        public void Initialize()
        {                

        }

        /// <summary>
        /// Shuffle deck.
        /// </summary>
        public Boolean Shuffle(int shuffleNum)
        {
            for (int m = shuffleNum; m > 0; m--)
            {
                //initialize variables

                //
                //Phase 1 variables - taking bottom of main deck and putting on top of right hand
                //
                //Random number 
                Random randomNum1 = new Random();
                //Number to take into right hand
                int rightHandSplit = randomNum1.Next(42, 62);
                //Number of empty spots left in main deck
                int emptySpots = MAXCARDS - rightHandSplit;
                //end Phase 1 variables

                //
                //Phase 2 variables - shuffling right hand deck back on top of main deck
                //
                //location to begin placing right hand cards back on the main deck
                int mainLoc = emptySpots;
                //index of the next card spot to get card placed in hand
                int shuffLoc = 1;
                //(random)the number of cards to move from shuffle hand to main hand
                int smallShuffNum = 0;
                //number of cards left to shuffle into the main hand
                int shuffLeft = emptySpots;
                //Random number 
                Random randomNum2 = new Random();
                //end Phase 2 variables


                //Move main deck starting at the split to top of right hand deck
                int split = rightHandSplit;
                for (int k = 1; k <= emptySpots; k++)
                {
                    rightHandDeck[k] = deck[split];
                    split++;
                }

                //erase the bottom part of the deck that you put on the top
                //mainly used for testing purposes
                //for (int i = rightHandSplit; i <= MAXCARDS - 1; i++)
                //{
                //    deck[i] = 999;
                //}

                int _tempMAXCARDS = MAXCARDS - 1;
                for (int i = rightHandSplit - 1; i >= 0; i--)
                {
                    deck[_tempMAXCARDS] = deck[i];
                    _tempMAXCARDS--;
                }

                //erase the top part of the deck that you shifted to bottom
                //for (int i = 1; i <= emptySpots; i++)
                //{
                //    deck[i] = 999;
                //}

                while (shuffLeft > 0)
                {
                    if (shuffLeft <= 6)
                    {
                        for (int i = shuffLeft; i > 0; i--)
                        {
                            deck[mainLoc] = rightHandDeck[shuffLoc + i - 1];
                            mainLoc--;
                        }
                        shuffLeft = 0;
                    }
                    else
                    {
                        smallShuffNum = randomNum2.Next(2, 5);
                        //smallShuffNum = 3;
                        for (int leftToAdd = smallShuffNum; leftToAdd > 0; leftToAdd--)
                        {
                            deck[mainLoc] = rightHandDeck[shuffLoc + leftToAdd - 1];
                            mainLoc--;
                        }
                        shuffLoc += smallShuffNum;
                        shuffLeft -= smallShuffNum;
                    }
                }
            }
            return true;
        }//END shuffle

        public static int[] SetDeck(string xmlPath)
        {

            //load the xml into an XmlDocument 
            XmlDocument doc = new XmlDocument(); 
            doc.Load(xmlPath); 

            //get all "CARD" nodes  
            XmlNodeList cardNodes = doc.SelectNodes("/BOARD_ORIENTATION_1/CARD"); 
            //create an array with sufficient space 
            int[] cards = new int[cardNodes.Count]; 

            //iterate through the XmlNodes and parse their string values to int 
            for (int cardIndex = 0; cardIndex < cardNodes.Count; cardIndex++) 
            { 
                cards[cardIndex] = int.Parse(cardNodes[cardIndex].InnerText); 
            }

            return cards;
            ////display the cards' values 
            //foreach (int number in cardValues)
            //{
            //    deck[number] = number;
            //} 
        }

        public string TranslateCardToText(int cardNum)
        {
            //Character for the face value of the card
            char face;
            //String for one or two digits of the value of card
            string num;
            //face + num concatenated for return
            string returnVal;            

            //set the suit of the card
            if (cardNum <= 13 && cardNum > 0)
                face = 'C';//Clubs
            else if (cardNum <= 26 && cardNum > 13)
                face = 'D';//Diamonds
            else if (cardNum <= 39 && cardNum > 26)
                face = 'H';//Hearts
            else if (cardNum <= 52 && cardNum > 39)
                face = 'S';//Spades
            else if (cardNum == 53)
                face = ' ';//free spot
            else//for errors
                face = 'X';


                if (cardNum != 53)
                {
                    //set the face of the card if necessary
                    switch (cardNum % 13)
                    {
                        case 0:
                            num = " K";//King
                            break;
                        case 1:
                            num = " A";//Ace
                            break;
                        case 11:
                            num = " J";//Jack
                            break;
                        case 12:
                            num = " Q";//Queen
                            break;

                        default:
                            num = Convert.ToString(cardNum % 13);
                            break;
                    }
                }
                else num = "FSP";
            
            //if the number is less than 10, pad to left for alignment
            if (num == "2" || num == "3" || num == "4" || num == "5" ||
                num == "6" || num == "7" || num == "8" || num == "9")
                num = num.PadLeft(2, ' ');
            
            //Concatonate the number and face of the car into one variable to return
            returnVal = num + face;

            return returnVal;
        }//END TranslateCardToText

        //deals the initial hands out to the players
        public void DealHand(Deck deck, int[] handA, int[] handB, int numToDeal)
        {
            for (int i = 1; i <= numToDeal; i++)
            {
                handA[i] = deck.deck[topCard];
                handB[i] = deck.deck[topCard + 1];
                topCard += 2;
            }
        }//END DealHand

        //deals a card into the given position.  Currently cannot deal more than one.
        public void DealHand(Deck deck, int[] handA, int removePos)
        {
                handA[removePos] = deck.deck[topCard];
                topCard++;
        }//END DealHand
    }
}